package org.gbif.metrics.ws.resources;

import org.gbif.ws.util.ExtraMediaTypes;

import java.io.IOException;
import java.util.Map.Entry;

import javax.ws.rs.GET;
import javax.ws.rs.Path;
import javax.ws.rs.Produces;
import javax.ws.rs.QueryParam;
import javax.ws.rs.core.MediaType;

import com.google.common.base.Optional;
import com.google.inject.Inject;
import com.urbanairship.datacube.Address;
import com.urbanairship.datacube.BucketTypeAndBucket;
import com.urbanairship.datacube.DataCubeIo;
import com.urbanairship.datacube.Dimension;
import com.urbanairship.datacube.ReadBuilder;
import com.urbanairship.datacube.ops.LongOp;


/**
 * A simple generic resource that will look up a numerical count from the named cube
 * and address provided.
 */
@Path("/cube")
@Produces({MediaType.APPLICATION_JSON, ExtraMediaTypes.APPLICATION_JAVASCRIPT})
public class AddressableCountResource {

  private final DataCubeIo<LongOp> cubeIo;

  @Inject
  public AddressableCountResource(DataCubeIo<LongOp> cubeIo) {
    this.cubeIo = cubeIo;
  }


  @Path("/occurrence")
  @GET
  /**
   * The conversion to the write builder is performed by the provider.
   * @see org.gbif.metrics.ws.resources.provider.CubeDimensionProvider
   */
  public AddressableCount count(@QueryParam("builder") ReadBuilder b) {
    AddressableCount ac = new AddressableCount();
    try {
      Address a = b.build();
      // capture the interpreted address for returning
      for (Entry<Dimension<?>, BucketTypeAndBucket> e : a.getBuckets().entrySet()) {
        ac.append(e.getKey().getName());
      }

      // lookup the actual count
      Optional<LongOp> o = cubeIo.get(a);
      if (o.isPresent()) {
        ac.setCount(o.get().getLong());
      }
    } catch (IOException e) {
      e.printStackTrace();
    } catch (InterruptedException e) {
      e.printStackTrace();
    }
    return ac;
  }
}
